package library.core;

import java.io.IOException;
import java.sql.SQLException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import java.sql.ResultSet;

import library.core.book.Book;
import library.core.user.Admin;
import library.core.user.Reader;
import library.core.user.User;
import library.database.user.DatabaseAdminProxy;
import library.database.user.DatabaseReaderProxy;
import library.utils.Info;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

// import com.mysql.cj.protocol.Resultset;


public class Library {
	/**
	 * 登录
	 * @param id
	 * @param password
	 * @return 登录成功返回用户对象，否则返回null
	 */
	public User login(String idstr, String password) {
		try {
			int id = Integer.valueOf(idstr);
			DatabaseReaderProxy proxy = new DatabaseReaderProxy();
			boolean flag = proxy.userLogin(id,password);
			if(!flag)
				return null;
			else {
				ResultSet rs = proxy.seek(id);
				int state = -1;
				String name = null;
				String email = null;
				String depart = null;
				while(rs.next()) {
					state = rs.getInt("state");
					name = rs.getString("name");
					email = rs.getString("email");
					depart = rs.getString("department");
					User u = null;
					if(state==1) {
						u = new Admin();
					}
					else {
						Reader r = new Reader();
						r.setFrozen(state==2);
						u = r;
					}
					u.setName(name);
					u.setEmail(email);
					u.setDepartment(depart);
					u.setId(id);
					return u;
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	
	/**
	 * 借阅信息
	 * @param user
	 * @param book
	 * @return 返回该用户关于该书的借阅信息，无则返回BorrowInfo.NO
	 * @throws SQLException
	 * @throws IOException
	 * @throws ClassNotFoundException
	 */
	public BorrowInfo borrowed(User user, Book book) {
		try {
			int userid = user.getId();
			int bkid = book.getId();
			DatabaseReaderProxy proxy = new DatabaseReaderProxy();
			ResultSet rs = proxy.showOneBrrowedBook(userid, bkid);
			DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
			while(rs.next())
			{
				Date beg = rs.getDate("start_time");
				Date end = rs.getDate("end_time");
				return new BorrowInfo(dateFormat.format(beg),dateFormat.format(end));
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return BorrowInfo.NO;
	}
	
	/**
	 * 返回所有书籍
	 * @return 所有书籍列表
	 * @throws SQLException
	 * @throws IOException
	 * @throws ClassNotFoundException
	 */
	public List<Book> getAllBooks() {
		ArrayList<Book> books = new ArrayList<Book>();
		try {
			DatabaseReaderProxy proxy = new DatabaseReaderProxy();
			ResultSet rs = proxy.showAllBooks();
			while(rs.next())
			{
				Book b = new Book();
				b.setName(rs.getString("name"));
				b.setAuthor(rs.getString("author"));
				b.setType(rs.getString("type"));
				b.setId(rs.getInt("id"));
				b.setPrice(rs.getDouble("price"));
				b.setNum(rs.getInt("num"));
				books.add(b);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return books;
	}
	
	/**
	 * 注册
	 * @param name
	 * @param pwd 密码
	 * @param pwd0 确认密码
	 * @param email
	 * @return 若注册失败返回提示信息，成功则返回Info.success("info")
	 */
	public Info register(String name, String pwd, String pwd0, String email,String department) {
		try {
			boolean f = false;
			DatabaseReaderProxy proxy = new DatabaseReaderProxy();
			if(name.length()==0)
				return new Info("用户名不能空");
			else if (pwd.length()==0)
				return new Info("密码不能为空");
			if (pwd.equals(pwd0))
				  {
					if(email!=null)
					{
//						if(!Pattern.matches("^(\\w+([-.][A-Za-z0-9]+)*){3,18}@\\w+([-.][A-Za-z0-9]+)*\\.\\w+([-.][A-Za-z0-9]+)*$",email));
//						  	return new Info("邮箱格式错误！");
					}
					if (pwd.length() > 18)
					  	return new Info("密码超过18个字符！");
					if(name.length()>255)
						return new Info("用户名超过255个字符！");
					f = proxy.insert(name, pwd, email, department);
					if(f==true)
					  	{
							ResultSet rs = proxy.getRegId();
							int id = -1;
							if(rs == null) return new Info("系统错误！");
							while(rs.next())
							{
								id = rs.getInt(1);
							}
							if(id < 0) return new Info("系统错误！");
							return Info.success("您的账户ID是："+String.valueOf(id));
							}
					else return new Info("系统错误，请稍后尝试！");	
					}
			else return new Info("两次输入密码不相等");
		} catch (Exception e) {
			e.printStackTrace();
			return new Info("系统错误");
		}
	}
	
	/**
	 * 添加书籍
	 * @param name
	 * @param author
	 * @param type
	 * @param price
	 * @return 若添加失败返回提示信息，成功则返回Info.success("info")
	 */
	public Info addBook(String name, String author, String type, String price, String num) {
		DatabaseAdminProxy adminproxy;
		try {
			adminproxy = new DatabaseAdminProxy();
			if(name.length() > 225 || name.length()==0)
				return new Info("书籍名字格式不正确！");
			if(author.length() >255)
				return new Info("作者名字过长！");
			if (type.length() >255)
				return new Info("书籍类型字数过长！");
			if(price!=null){
					Pattern pattern = Pattern.compile("[0-9]+[.]{0,1}[0-9]*[dD]{0,1}");
					Matcher isDouble = pattern.matcher(price);
					if(!isDouble.matches())
						return new Info("书籍价格信息错误！");		
			}
			if(num!=null){
				boolean isNum = num.matches("[0-9]+");
				if(!isNum)
					return new Info("书籍数量信息错误！");
			}
			boolean flag = adminproxy.addBooks(name, author, type, Double.valueOf(price),Integer.valueOf(num));
			if(!flag)
				return new Info("系统错误！");
			else return Info.success("");
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return new Info("系统错误！");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return new Info("系统错误！");
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return new Info("系统错误！");
		}
	}
	
	/**
	 * 删除书籍
	 * @param book
	 * @return
	 */
	public Info deleteBook(Book book){
		try {
			DatabaseAdminProxy adminproxy = new DatabaseAdminProxy();
			int id = book.getId();
			boolean flag = adminproxy.checkifex(id);
			if(!flag)
				return new Info("该书籍不存在！");
			flag = adminproxy.deleteBook(id);
			if(!flag)
				return new Info("系统错误！");
			else return Info.success("");
		} catch (SQLException e) {
			e.printStackTrace();
			return new Info("系统错误！");
		}catch (IOException e){
			e.printStackTrace();
			return new Info("系统错误！");
		}catch (ClassNotFoundException e){
			e.printStackTrace();
			return new Info("系统错误！");
		}
	}
	
	/**
	 * 借阅书籍
	 * @param user
	 * @param book
	 * @return
	 */
	public Info borrow(User user, Book book){
		try {
			int bkid = book.getId();
			int userid = user.getId();
			DatabaseReaderProxy readerproxy;
			readerproxy = new DatabaseReaderProxy();
			int num = readerproxy.checkbooknum(bkid);
			if(num<=0) return new Info("在架库存不足！");
			else{
				boolean flag = false;//检查是否已经借阅该本书
				ResultSet rs = readerproxy.showOneBrrowedBook(userid, bkid);
				while (rs.next()){
					flag = true;
				}
				if(flag)
					return new Info("已经借阅该书！");
				boolean flag2 = readerproxy.borrowbook(bkid, userid);
				if(flag2) return Info.success("");
				else return new Info("系统错误！");
			}
		} catch (Exception e) {
			e.printStackTrace();
			return new Info("系统错误！");
		}
	}
	
	/**
	 * 归还书籍
	 * @param user
	 * @param book
	 * @return
	 */
	public Info returnBook(User user, Book book) {
		try {
			DatabaseReaderProxy readerproxy = new DatabaseReaderProxy();
			ResultSet rs = readerproxy.showOneBrrowedBook(user.getId(),book.getId());
			if(rs.next()==false) return new Info("没有借阅该书籍！");
			boolean flag = readerproxy.checkbook(book.getId());
			if(!flag) return new Info("该书籍不存在！");
			flag = readerproxy.returnBooks(user.getId(), book.getId());
			if(!flag) return new Info("系统错误！");
			return Info.success("");
		} catch (ClassNotFoundException | IOException | SQLException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
			return new Info("系统错误！");
		}
	}	
	
	/**
	 * 在借数量
	 * @param book
	 * @return
	 */
	public int getBorrowedNum(Book book) {
		try {
			DatabaseAdminProxy adminproxy = new DatabaseAdminProxy();
			int num = adminproxy.getBonum(book.getId());
			return num;
		} catch (ClassNotFoundException | IOException | SQLException e) {
			e.printStackTrace();
			return 0;
		}
	}
	
	public List<Book> pickByName(String name, List<Book> list){
		if("".equals(name)) return list;
		return list.stream().filter((b)->b.getName().contains(name)).toList();
	}
	
	public List<Book> pickByAuthor(String name, List<Book> list){
		if("".equals(name)) return list;
		return list.stream().filter((b)->b.getAuthor().contains(name)).toList();
	}
	
	public boolean available(Book book) {
		return book.getNum() > 0;
	}

	public List<Book> pickBorrowed(User user, List<Book> list){
		return list.stream().filter((b)->!(borrowed(user, b).no())).toList();
	}

	public List<Book> pickAvailable(User user, List<Book> list){
		return list.stream().filter((b)->available(b)).toList();
	}
	
	public static class BorrowInfo {
		
		public static final BorrowInfo NO = new BorrowInfo();
		
		private String beg, end;
		
		private BorrowInfo() {}
		/**
		 * @param beg 借阅日期
		 * @param end 归还日期
		 */
		public BorrowInfo(String beg, String end) {
			this.beg = beg;
			this.end = end;
		}
		
		public boolean no() {
			return this == NO;
		}
		
		public String getBegin() {
			return beg;
		}
		
		public String getEnd() {
			return end;
		}
		
	}
	
}
